﻿Public Class BrowseBuddies
    Private mCurrentClient As NetNode.Client
    Private mCurrentClientShare As Entities.SharedWatchFolder
    Private mCurrentClientShareDirectoryCode As String
    Private mWaitingForMessageIdEx As Integer
    Private mEnterBuddyWhenConnected As Entities.Buddy

    Private mCurrentView As CurrentView
    Private Enum CurrentView
        Buddies
        Shares
        Items
    End Enum

    Private Class ImageKeys
        Public Const Folder As String = "f"
        Public Const Movie As String = "m"
        Public Const TVSeries As String = "t"
        Public Const BuddyOnline As String = "bu"
        Public Const BuddyOffline As String = "bo"
    End Class

    Public Sub Init()
        mCurrentView = CurrentView.Buddies
        mCurrentClient = Nothing
        mCurrentClientShare = Nothing

        ImageList1.Images.Add(ImageKeys.Folder, My.Resources.Folder2)
        ImageList1.Images.Add(ImageKeys.Movie, My.Resources.Movie)
        ImageList1.Images.Add(ImageKeys.TVSeries, My.Resources.TV)
        ImageList1.Images.Add(ImageKeys.BuddyOnline, CommonResources.My.Resources.Buddy_Online)
        ImageList1.Images.Add(ImageKeys.BuddyOffline, CommonResources.My.Resources.Buddy_Offline)


        AddHandler NetNode.Manager.ClientStatusChanged, AddressOf EventHandler_ClientStatusChanged
        AddHandler FileShare.Manager.GetSharesReply, AddressOf EventHandler_GetSharesReply
        AddHandler FileShare.Manager.GetShareItemsReply, AddressOf EventHandler_GetShareItemsReply
        AddHandler DataStore.Buddies.BuddyCreated, AddressOf EventHandler_BuddyCreated
        AddHandler DataStore.Buddies.BuddyDeleted, AddressOf EventHandler_BuddyDeleted
        AddHandler DataStore.Buddies.BuddyUpdated, AddressOf EventHandler_BuddyUpdated

        UpdateView()
    End Sub
    Public Sub [Stop]()
        RemoveHandler NetNode.Manager.ClientStatusChanged, AddressOf EventHandler_ClientStatusChanged
        RemoveHandler FileShare.Manager.GetSharesReply, AddressOf EventHandler_GetSharesReply
        RemoveHandler FileShare.Manager.GetShareItemsReply, AddressOf EventHandler_GetShareItemsReply
        RemoveHandler DataStore.Buddies.BuddyCreated, AddressOf EventHandler_BuddyCreated
        RemoveHandler DataStore.Buddies.BuddyDeleted, AddressOf EventHandler_BuddyDeleted
        RemoveHandler DataStore.Buddies.BuddyUpdated, AddressOf EventHandler_BuddyUpdated
    End Sub

    Private Sub EventHandler_BuddyCreated(ByVal buddy As Entities.Buddy)
        Try
            If mCurrentView = CurrentView.Buddies Then UpdateItem(buddy, False)
        Catch ex As Exception
            Utils.Misc.HandleException(Me, ex)
        End Try
    End Sub
    Private Sub EventHandler_BuddyUpdated(ByVal buddy As Entities.Buddy)
        Try
            If mCurrentView = CurrentView.Buddies Then UpdateItem(buddy, False)
        Catch ex As Exception
            Utils.Misc.HandleException(Me, ex)
        End Try
    End Sub
    Private Sub EventHandler_BuddyDeleted(ByVal buddy As Entities.Buddy)
        Try
            If mCurrentView = CurrentView.Buddies Then
                For Each clsItem As ListViewItem In ListView1.Items
                    If TypeOf clsItem.Tag Is Entities.Buddy AndAlso CType(clsItem.Tag, Entities.Buddy).Id = buddy.Id Then
                        clsItem.Remove()
                        Exit For
                    End If
                Next
            ElseIf mCurrentClient.Buddy.Id = buddy.Id Then
                mCurrentView = CurrentView.Buddies
                UpdateView()
            End If
        Catch ex As Exception
            Utils.Misc.HandleException(Me, ex)
        End Try
    End Sub

    Private Sub EventHandler_GetSharesReply(ByVal client As NetNode.Client, ByVal reply As Commands.GetShares.Reply)
        Try
            If mWaitingForMessageIdEx = reply.InReplyToMessageId Then
                ListView1.BeginUpdate()
                ListView1.Items.Clear()
                ListView1.Groups.Clear()
                ListView1.ShowGroups = True

                For Each clsGroup As Commands.GetShares.Group In reply.Groups
                    Dim clsLVG As New ListViewGroup
                    clsLVG.Name = clsGroup.Name
                    clsLVG.Header = clsGroup.Name
                    clsLVG.HeaderAlignment = HorizontalAlignment.Left
                    ListView1.Groups.Add(clsLVG)

                    For Each clsShare As Entities.SharedWatchFolder In clsGroup.Shares
                        With ListView1.Items.Add(clsShare.Name)
                            .SubItems.Add(String.Empty)
                            .SubItems.Add(String.Format("Share ({0})", clsShare.ItemTypes))
                            .Tag = clsShare
                            .Group = clsLVG
                            Select Case clsShare.ItemTypes
                                Case Entities.ItemType.Movies
                                    .ImageKey = ImageKeys.Movie
                                Case Entities.ItemType.TVSeries
                                    .ImageKey = ImageKeys.TVSeries
                            End Select
                        End With
                    Next
                    For Each clsFilter As Commands.GetShares.Filter In clsGroup.Filters
                        With ListView1.Items.Add(clsFilter.Name)
                            .SubItems.Add(String.Empty)
                            .SubItems.Add("Filter")
                            .Tag = clsFilter
                            .Group = clsLVG
                        End With
                    Next
                Next
                ListView1.EndUpdate()
                ListView1.Enabled = True
            End If
        Catch ex As Exception
            Utils.Misc.HandleException(Me, ex)
        End Try
    End Sub

    Private Sub EventHandler_GetShareItemsReply(ByVal client As NetNode.Client, ByVal reply As Commands.GetShareItems.Reply)
        Try
            If mWaitingForMessageIdEx = reply.InReplyToMessageId Then
                ListView1.BeginUpdate()
                ListView1.Items.Clear()
                ListView1.Groups.Clear()

                ListView1.ShowGroups = reply.Groups.Count > 0

                For Each clsGroup As Commands.GetShareItems.Group In reply.Groups
                    Dim clsLVG As ListViewGroup = Nothing
                    If Not clsGroup.Hidden Then
                        clsLVG = New ListViewGroup
                        clsLVG.Name = clsGroup.Name
                        clsLVG.Header = clsGroup.Name
                        clsLVG.HeaderAlignment = HorizontalAlignment.Left
                        ListView1.Groups.Add(clsLVG)
                    End If

                    For Each clsDirectory As Commands.GetShareItems.Directory In clsGroup.Directories
                        Dim clsItem As New ListViewItem
                        With clsItem
                            .Text = clsDirectory.Name
                            .SubItems.Add(String.Empty)
                            .SubItems.Add(String.Format("Directory"))
                            .Tag = clsDirectory
                            .ImageKey = ImageKeys.Folder
                            If Not clsGroup.Hidden Then .Group = clsLVG
                        End With
                        ListView1.Items.Add(clsItem)
                    Next

                    For Each clsItem As Entities.SharedItem In clsGroup.Items
                        Dim clsLVI As New ListViewItem
                        With clsLVI
                            .Text = clsItem.Name
                            .SubItems.Add(Utils.Misc.ToReadableFileSize(clsItem.TotalSize))
                            .SubItems.Add(clsItem.ItemType.ToString)
                            .SubItems.Add(clsItem.Added.ToString("g"))
                            .SubItems.Add(clsItem.LastChanged.ToString("g"))
                            .Tag = clsItem
                            If Not clsGroup.Hidden Then .Group = clsLVG
                        End With
                        ListView1.Items.Add(clsLVI)
                    Next
                Next
                ListView1.EndUpdate()
                ListView1.Enabled = True
            End If
        Catch ex As Exception
            Utils.Misc.HandleException(Me, ex)
        End Try
    End Sub

    Private Sub EventHandler_ClientStatusChanged(ByVal client As NetNode.Client)
        Try
            If mCurrentView = CurrentView.Buddies Then
                If client.Buddy IsNot Nothing Then
                    UpdateItem(client.Buddy, False)
                    If mEnterBuddyWhenConnected IsNot Nothing Then
                        If client.IsOnline And client.Buddy.Id = mEnterBuddyWhenConnected.Id Then
                            EnterSelectedBuddy(client)
                        End If
                    End If
                End If
            ElseIf mCurrentClient Is client Then
                StopAllAsynchOperations()
                mCurrentClient = Nothing
                mCurrentView = CurrentView.Buddies
                UpdateView()
            End If
        Catch ex As Exception
            Utils.Misc.HandleException(Me, ex)
        End Try
    End Sub

    Private Sub StopAllAsynchOperations()
        mEnterBuddyWhenConnected = Nothing
        mWaitingForMessageIdEx = 0
    End Sub


    Private Sub UpdateView()
        StopAllAsynchOperations()
        ListView1.BeginUpdate()
        ListView1.Items.Clear()
        ListView1.Groups.Clear()
        ListView1.ShowGroups = False

        Select Case mCurrentView
            Case CurrentView.Buddies
                tslCurrentPath.Text = "\"
                ListView1.Groups.Add("ONLINE", "Online")
                ListView1.Groups.Add("OFFLINE", "Not online")
                ListView1.ShowGroups = True
                For Each clsBuddy As Entities.Buddy In DataStore.Buddies.GetAll
                    UpdateItem(clsBuddy, True)
                Next
                ListView1.Enabled = True
            Case CurrentView.Shares
                tslCurrentPath.Text = String.Format("\{0}", mCurrentClient.Buddy.Name)
                ListView1.Items.Add("Loading...")
                ListView1.Enabled = False
                mWaitingForMessageIdEx = Manager.StartGetShares(mCurrentClient)
            Case CurrentView.Items
                tslCurrentPath.Text = String.Format("\{0}\{1}{2}", mCurrentClient.Buddy.Name, mCurrentClientShare.Name, mCurrentClientShareDirectoryCode)
                ListView1.Items.Add("Loading...")
                ListView1.Enabled = False
                mWaitingForMessageIdEx = Manager.StartGetShareItems(mCurrentClient, mCurrentClientShare, mCurrentClientShareDirectoryCode)
        End Select

        ListView1.EndUpdate()
    End Sub

    ''Private Sub RemoveItem(ByVal client As NetNode.Client)
    ''    For Each clsTmpItem As ListViewItem In ListView1.Items
    ''        If CType(clsTmpItem.Tag, NetNode.Client) Is client Then
    ''            ListView1.Items.Remove(clsTmpItem)
    ''            Exit For
    ''        End If
    ''    Next
    ''End Sub

    Private Sub UpdateItem(ByVal buddy As Entities.Buddy, ByVal fromLoad As Boolean)
        Dim clsItem As ListViewItem = Nothing
        If Not fromLoad Then
            For Each clsTmpItem As ListViewItem In ListView1.Items
                If CType(clsTmpItem.Tag, Entities.Buddy).Id = buddy.Id Then
                    clsItem = clsTmpItem
                    Exit For
                End If
            Next
        End If
        If clsItem Is Nothing Then
            clsItem = ListView1.Items.Add(String.Empty)
            clsItem.SubItems.Add(String.Empty)
            clsItem.SubItems.Add(String.Empty)
        End If

        Dim clsClient As NetNode.Client = NetNode.Manager.GetOnlineByBuddyId(buddy.Id)

        If clsClient IsNot Nothing AndAlso clsClient.IsOnline Then
            clsItem.Text = buddy.Name
            clsItem.Group = ListView1.Groups("ONLINE")
            clsItem.ImageKey = ImageKeys.BuddyOnline
        Else
            clsItem.Text = String.Format("{0} (offline)", buddy.Name)
            clsItem.Group = ListView1.Groups("OFFLINE")
            clsItem.ImageKey = ImageKeys.BuddyOffline
        End If
        clsItem.SubItems(1).Text = String.Empty
        clsItem.SubItems(2).Text = String.Empty
        clsItem.Tag = buddy
    End Sub

    Private Sub ListView1_MouseDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListView1.MouseDoubleClick
        Select Case mCurrentView
            Case CurrentView.Buddies
                EnterSelectedBuddy()
            Case CurrentView.Shares
                EnterSelectedShare()
            Case CurrentView.Items
                EnterSelectedItem()
        End Select
    End Sub

    Private Sub EnterSelectedItem()
        If ListView1.SelectedItems.Count <> 1 Then Beep() : Return
        Dim clsTag As Object = ListView1.SelectedItems(0).Tag
        If TypeOf clsTag Is Commands.GetShareItems.Directory Then
            mCurrentClientShareDirectoryCode = CType(clsTag, Commands.GetShareItems.Directory).Code
            UpdateView()
        ElseIf TypeOf clsTag Is Entities.SharedItem Then
            Dim clsItem As Entities.SharedItem = CType(clsTag, Entities.SharedItem)
            FViewSharedItemDetails_Remote.Show(Me, mCurrentClient, clsItem)
        End If
    End Sub

    Private Sub EnterSelectedBuddy(Optional ByVal client As NetNode.Client = Nothing)
        Dim clsBuddy As Entities.Buddy = Nothing
        If client Is Nothing Then
            If ListView1.SelectedItems.Count <> 1 Then Beep() : Return
            clsBuddy = CType(ListView1.SelectedItems(0).Tag, Entities.Buddy)
            client = NetNode.Manager.GetOnlineByBuddyId(clsBuddy.Id)
        End If
        If client IsNot Nothing AndAlso client.IsOnline Then
            mCurrentClient = client
            mCurrentView = CurrentView.Shares
            UpdateView()
        ElseIf clsBuddy IsNot Nothing Then
            Select Case MessageBox.Show(Me, String.Format("{0} is not online! Would you like to attempt to connect?", clsBuddy.Name), "Connect?", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
                Case DialogResult.Yes
                    NetNode.Manager.StartConnect(clsBuddy, False)
                    mEnterBuddyWhenConnected = clsBuddy
            End Select
        End If
    End Sub
    Private Sub EnterSelectedShare()
        If ListView1.SelectedItems.Count <> 1 Then Beep() : Return
        Dim clsItem As Entities.SharedWatchFolder = CType(ListView1.SelectedItems(0).Tag, Entities.SharedWatchFolder)
        mCurrentClientShare = clsItem
        mCurrentView = CurrentView.Items
        mCurrentClientShareDirectoryCode = Nothing
        UpdateView()
    End Sub

    Private Sub MoveToParentFolder()
        Select Case mCurrentView
            Case CurrentView.Buddies
                Return 'do nothing 
            Case CurrentView.Shares
                mCurrentClient = Nothing
                mCurrentView = CurrentView.Buddies
            Case CurrentView.Items
                If String.IsNullOrEmpty(mCurrentClientShareDirectoryCode) Then
                    mCurrentClientShare = Nothing
                    mCurrentView = CurrentView.Shares
                Else
                    Dim iPos As Integer = mCurrentClientShareDirectoryCode.LastIndexOf("\"c)
                    If iPos <= 0 Then
                        mCurrentClientShareDirectoryCode = Nothing
                    Else
                        mCurrentClientShareDirectoryCode = mCurrentClientShareDirectoryCode.Substring(0, iPos)
                    End If
                End If
            Case Else
                Return
        End Select
        UpdateView()
    End Sub

    Private Sub tsbUpFolder_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbUpFolder.Click
        Try
            MoveToParentFolder()
        Catch ex As Exception
            Utils.Misc.HandleException(Me, ex)
        End Try
    End Sub

End Class
